package hujz.java.file_server._default;

import hujz.java.file_server.IOathInterceptor;
import hujz.java.file_server.http.DispatcherHandler;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.*;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.Principal;
import java.util.List;

public class OathInterceptor implements IOathInterceptor {
    private final Logger LOGGER = LoggerFactory.getLogger(DispatcherHandler.class);

    public static class OathInfo {
        public String uuid;
        public String token;
        public Long expire;
        public String loginId;
    }

    public static interface ValidateToken {
        OathInfo valid(String token);
    }

    private ValidateToken validateToken;

    public void setValidateToken(ValidateToken validateToken) {
        this.validateToken = validateToken;
    }

    @Override
    public boolean intercept(ChannelHandlerContext ctx, HttpRequest request) {
        String oath2 = (request).headers().get("Authorization");
        if (oath2 == null) {
            QueryStringDecoder decoderQuery = new QueryStringDecoder(request.uri());
            List<String> token = decoderQuery.parameters().get("token");
            oath2 = token != null && token.size() != 0 ? token.get(0) : null;
        } else {
            if (oath2.startsWith("Bearer") && oath2.length() > "Bearer".length()) {
                oath2 = oath2.substring("Bearer".length() + (oath2.charAt("Bearer".length()) == ' ' ? 1 : 0));
            }
        }
        if (oath2 == null) {
            LOGGER.warn("[FileServer] <-- non-oath2-token");
            ctx.channel().write(new DefaultHttpResponse(HttpVersion.HTTP_1_0, HttpResponseStatus.UNAUTHORIZED)).addListener(ChannelFutureListener.CLOSE);
            ctx.channel().flush();
            ctx.channel().close();
            return false;
        } else {
            LOGGER.debug("[FileServer] --- oath2-token: {}", oath2);
            String auth = validateToken.valid(oath2).uuid;
            if (auth == null) {
                ctx.channel().write(new DefaultHttpResponse(HttpVersion.HTTP_1_0, HttpResponseStatus.UNAUTHORIZED)).addListener(ChannelFutureListener.CLOSE);
                ctx.channel().flush();
                ctx.channel().close();
                return false;
            }
            AttributeKey<Principal> attributeKey = AttributeKey.exists("Principal") ? AttributeKey.valueOf("Principal") : AttributeKey.newInstance("Principal");
            Attribute<Principal> attribute = ctx.channel().attr(attributeKey);
            attribute.set(() -> auth);
        }
        return true;
    }
}
